home *** CD-ROM | disk | FTP | other *** search
/ The Atari Compendium / The Atari Compendium (Toad Computers) (1994).iso / files / prgtools / gnustuff / tos / util / utlsrc37.zoo / cnm.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-06-30  |  6.7 KB  |  388 lines

  1. /* Copyright (c) 1988 by Sozobon, Limited.  Author: Johann Ruegg
  2.  *
  3.  * Permission is granted to anyone to use this software for any purpose
  4.  * on any computer system, and to redistribute it freely, with the
  5.  * following restrictions:
  6.  * 1) No charge may be made other than reasonable charges for reproduction.
  7.  * 2) Modified versions must be clearly marked as such.
  8.  * 3) The authors are not responsible for any harmful consequences
  9.  *    of using this software, even if they result from defects in it.
  10.  *
  11.  *    Alternative ST symbol table lister.
  12.  */
  13.  
  14. /* highly munged from above, VERY quick and dirty nm, just enough
  15.    here to find _stksize for fixstk.c and printstk.c, may be
  16.    useful for other stuff.
  17.  
  18.    WARNING: -g option will not work with gcc-ld produced a.out
  19.  
  20.  
  21.      ++jrb
  22.  */
  23.  /*
  24.  * Modified to handle expanded, GST linker derived, format for symbols.
  25.  * This format is produced with -G flag to a proper version of gcc-ld.
  26.  * -g flag also will work if ld coached properly.
  27.  *
  28.  *   --mj
  29.  */
  30.  
  31. /*
  32.  * ++jrb rework and cleanup while adding A_TFILE A_TFARC
  33.  */
  34.  
  35. #include <compiler.h>
  36. #include <stdio.h>
  37. #include <st-out.h>
  38. #include <stdlib.h>
  39.  
  40. #if __STDC__
  41. #include <stdlib.h>
  42. #else
  43. extern char *malloc(), *realloc();
  44. #endif
  45.  
  46. #ifdef atarist
  47. # define READB    "rb"
  48. #else
  49. # define READB "r"
  50. #endif
  51.  
  52. #if !__STDC__ && !defined(hpux)
  53. typedef unsigned long size_t;
  54. #endif
  55.  
  56. #ifndef WORD_ALIGNED
  57. # define SIZEOF_SYM ((size_t)sizeof(struct asym))
  58. #else
  59. # define SIZEOF_SYM ((size_t)14)
  60. #endif
  61.  
  62. struct xsym {
  63.     char name[8];
  64.     union {
  65.     unsigned char  _flags[2];
  66.     unsigned short _sflgs;
  67.     } u;
  68.     unsigned long value;
  69.     char tail[SIZEOF_SYM];
  70. };
  71.  
  72. #define flags    u._flags[0]
  73. #define xflags  u._flags[1]
  74. #define sflgs   u._sflgs
  75.  
  76. #ifdef __STDC__
  77. # define P(s) s
  78. #else
  79. # define P(s) ()
  80. #endif
  81.  
  82. int main P((int argc , char **argv ));
  83. int cmp P((struct xsym *s1 , struct xsym *s2 ));
  84. int doname P((char *s , int many ));
  85. long dohdr P((FILE *fd ));
  86. void dosym P((struct xsym *s ));
  87. int not_glob P((unsigned int x ));
  88. void sflags P((struct xsym *s ));
  89. void ckfread P((void *buf , int siz , int n , FILE *fp ));
  90. long readhead P((struct aexec *h , int n , FILE *fd ));
  91. int readsyms P((struct xsym *syms , int n , FILE *fd ));
  92. void usage P((void ));
  93.  
  94. #undef P
  95.  
  96.  
  97. int gflag;
  98. int uflag;
  99.  
  100. int main(argc, argv)
  101. int argc;
  102. char **argv;
  103. {
  104.     int c, status = 0;
  105.     extern char *optarg;
  106.     extern int optind;
  107.     while ((c = getopt(argc, argv, "gu")) != -1)
  108.     switch (c)
  109.     {
  110.       case 'g':
  111.         gflag = 1;
  112.         break;
  113.       case 'u':
  114.         uflag = 1;
  115.         break;
  116.       case '?':
  117.         usage();
  118.     }
  119.     c = argc - optind;
  120.     if(c <= 0)
  121.     usage();
  122.     
  123.     for (; optind < argc; optind++) 
  124.     status |= doname(argv[optind], (c > 1));
  125.     return status;
  126. }
  127.  
  128. int  cmp(s1, s2)
  129. struct xsym *s1, *s2;
  130. {
  131.   long diff = s1->value - s2->value;
  132.   return (diff > 0) - (diff < 0);
  133. }
  134.  
  135. int doname(s, many)
  136. char *s;
  137. int many;
  138. {
  139.     FILE *fd, *fopen();
  140.     long i, count;
  141.  
  142.     if(!(fd = fopen(s, READB)))
  143.     {
  144.     perror(s);
  145.     return 2;
  146.     }
  147.     if (many)
  148.     printf("\n%s:\n", s);
  149.  
  150.     if (i = dohdr(fd))
  151.     {
  152.     struct xsym *syms, *savesyms;
  153.     struct xsym *currsym;
  154.     printf("%ld slots mem %ld\n", i, (long)(i*sizeof(struct xsym)));
  155.     
  156.     if((savesyms = syms = (struct xsym *)malloc(i*sizeof(struct xsym))) == NULL)
  157.     {
  158.         perror("Outa mem");
  159.         exit(4);
  160.     }
  161.     count = i;
  162.     currsym = syms;
  163.     while (count)
  164.     {
  165.         if(readsyms(currsym, 1, fd) != 1)
  166.         {
  167.         perror("reading syms");
  168.         exit(8);
  169.         }
  170.         if (--count)
  171.         {
  172.         if (A_LNAM == (currsym->xflags & A_LNAM))
  173.         {
  174.             if(fread(currsym->tail, SIZEOF_SYM, 1, fd) != 1)
  175.             {
  176.             perror("reading syms");
  177.             exit(16);
  178.             }
  179.             --i;
  180.             --count;
  181.         }
  182.         }
  183.         else /* object was partially stripped */
  184.         currsym->xflags &= ~A_LNAM;        
  185.         if (gflag && not_glob((unsigned int)(currsym->flags)))
  186.         --i;
  187.         else
  188.         currsym++;
  189.     }
  190.     fclose(fd);
  191.     printf("%ld %s symbol(s)\n", i, (gflag ? "global ": ""));
  192.     if (!uflag)
  193.       qsort(syms, i, sizeof(struct xsym), cmp);
  194.     while (i--)
  195.     {
  196.         dosym(syms);
  197.         syms += 1;
  198.     }
  199.     free(savesyms);
  200.     }
  201.     return 0;
  202. }
  203.  
  204. long dohdr(fd)
  205. FILE *fd;
  206. {
  207.     struct aexec h;
  208.     long i;
  209.         
  210.     i = readhead(&h, 1, fd);
  211.     if (i != 1 || h.a_magic != CMAGIC)
  212.     {
  213.     fprintf(stderr, "Bad header\n");
  214.     return 0L;
  215.     }
  216.     fseek(fd, (h.a_text + h.a_data), 1);
  217.     return h.a_syms / SIZEOF_SYM;
  218. }
  219.  
  220. void
  221. dosym(s)
  222. struct xsym *s;
  223. {
  224.     printf("%-8.8s", s->name);
  225.     printf("%-14.14s", (A_LNAM == (s->xflags & A_LNAM) ? s->tail : ""));
  226.     printf("\t%8lx ", s->value);
  227.     s->xflags &= ~A_LNAM;
  228.     sflags(s);
  229.     putchar('\n');
  230. }
  231.  
  232. char *fname[] = {
  233.     "?0?", " bss", " text", "?3?", " data",
  234.     "?5?", "?6?", "?7?"
  235. };
  236. char *Fname[] = {
  237.     "?0?", "Bss", "Text", "?3?", "Data",
  238.     "?5?", "?6?", "?7?"
  239. };
  240.  
  241. int not_glob(x)
  242. unsigned int x;
  243. {
  244.     x &= 0xff;
  245.     if (x & 0x20)
  246.         return 0;
  247.     x &= ~0x20;
  248.     if (x == 0x88)
  249.         return 0;
  250.     return 1;
  251. }
  252.  
  253. void
  254. sflags(s)
  255. struct xsym *s;
  256. {
  257.     unsigned int x = s->flags;
  258.     char **category;
  259.     int lflag;
  260.     
  261.     if(s->sflgs == A_TFILE)
  262.     printf("text file");
  263.     else if (s->sflgs == A_TFARC)
  264.     printf("text file archive");
  265.     else
  266.     {
  267.     if (0 != (lflag = not_glob(x)))
  268.         category = fname;
  269.     else
  270.         category = Fname;
  271.  
  272.     x &= 0xff;
  273.     if (x & 0x20)
  274.         printf("global ");
  275.     x &= ~0x20;
  276.     if (x & 0xd8)
  277.     {
  278.         if (x & 0x08)
  279.         printf (" external");
  280.         if (x & 0x50)
  281.         {
  282.         printf (" equ");
  283.         if (x & 0x10)
  284.             printf (" reg");
  285.         }
  286.         if (x & 0x80)
  287.         printf (" abs");
  288.         if (!lflag)
  289.         printf(" G");
  290.     }
  291.     else
  292.     {
  293.         x &= 7;
  294.         printf(category[x]);
  295.     }
  296.     }
  297.     printf(" (0x%04x)",(unsigned int)(s->sflgs));
  298. }
  299.  
  300. void ckfread(buf, siz, n, fp)
  301. void *buf;
  302. int siz, n;
  303. FILE *fp;
  304. {
  305.     if(fread(buf, siz, n, fp) != n)
  306.     {
  307.         perror("reading");
  308.         exit(32);
  309.     }
  310. }
  311.  
  312. long readhead(h, n, fd)
  313. struct aexec *h;
  314. int n;
  315. FILE *fd;
  316. {
  317.     short i;
  318.     long j;
  319.     int k;
  320.  
  321.     for(k = 0; k < n; k++)
  322.     {
  323.     ckfread(&i, 2, 1, fd);
  324.     h->a_magic = i;
  325.     ckfread(&j, 4, 1, fd);
  326.     h->a_text = j;
  327.     ckfread(&j, 4, 1, fd);
  328.     h->a_data = j;
  329.     ckfread(&j, 4, 1, fd);
  330.     h->a_bss = j;
  331.     ckfread(&j, 4, 1, fd);
  332.     h->a_syms = j;
  333.     ckfread(&j, 4, 1, fd);
  334.     h->a_AZero1 = j;
  335.     ckfread(&j, 4, 1, fd);
  336.     h->a_ldflgs = j;
  337.     ckfread(&i, 2, 1, fd);
  338.     h->a_isreloc = i;
  339.     }
  340.     return k;
  341. }
  342.  
  343. int readsyms(syms, n, fd)
  344. struct xsym *syms;
  345. int n;
  346. FILE *fd;
  347. {
  348.     int k;
  349.  
  350.     for(k = 0; k < n; k++, syms++)
  351.     {
  352.     ckfread(syms->name, 8, 1, fd);
  353.     ckfread(&(syms->sflgs), 2, 1, fd);
  354.     ckfread(&(syms->value), 4, 1, fd);
  355.    }
  356.    return k;
  357. }
  358.  
  359. void usage()
  360. {
  361.     fprintf(stderr, "cnm [-g] files...\n");
  362.     exit(1);
  363. }
  364.  
  365. #if !defined(__GNUC__) &&  defined(hpux)
  366.  
  367. char *xmalloc(n)
  368. int n;    /* sigh! */
  369. {
  370.    char *ret = (char *)malloc(n);
  371.  
  372.    if(ret) return ret;
  373.    perror("malloc");
  374.    exit(1);
  375. }
  376.  
  377. char *xrealloc(b, n)
  378. char * b;
  379. int n;    /* sigh! */
  380. {
  381.    char *ret = (char *)realloc(b, n);
  382.  
  383.    if(ret) return ret;
  384.    perror("realloc");
  385.    exit(2);
  386. }
  387. #endif
  388.